package com.apobates.forum.toro.proxy.strategy;

import com.apobates.forum.toro.proxy.MapperAttrExpression;
import com.apobates.forum.toro.proxy.MapperAttrStatements;
import com.apobates.forum.toro.utils.BeanHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MapperSerialStrategy<E,T> implements MapperStrategy<E,T> {
    private static final Logger logger = LoggerFactory.getLogger(MapperSerialStrategy.class);
    @Override
    public void consumer(Stream<MapperAttrExpression> selectExprStream, E targetObj, T selectObj) {
        logger.debug("[MPS][Serial]one serial strategy start");
        // 批量设置(S3)
        Function<MapperAttrExpression,String> keyFun = (maqK)-> maqK.getTargetAttr();
        Function<MapperAttrExpression,Object> valFun = (maqV)->{
            try {
                // selectAttrTypeName
                Class<?> selectAttrType = null;
                try {
                    selectAttrType = BeanHelper.getTypeClass(maqV.getSelectAttrTypeName());
                }catch (Exception e){
                    System.out.println("[MPS][Serial]calc select function argument has error:"+e.getMessage());
                }
                MapperAttrStatements.Argument args = maqV.buildRelationArgs();
                // 查询函数的参数值
                Object selectAttrVal = (null == selectAttrType)
                        ? BeanHelper.getAttrVal(selectObj, maqV.getSelectAttr())
                        : BeanHelper.getAttrVal(selectObj, maqV.getSelectAttr(), selectAttrType);
                //String selectAttrVal = BeanUtils.getProperty(selectObj, maqV.getSelectAttr());
                Object tmp = maqV.getSelectFun().apply(selectAttrVal.toString());
                if(!args.isTargetAttrSet()) {
                    return Optional.ofNullable(tmp).orElse(null); // Bean无值时等于null
                } else {
                    return (null==tmp) ? BeanHelper.buildInstance(Class.forName(args.getCollectionType())) : tmp; // 集合无值时等于空集合
                }
            }catch (Exception e){
                logger.debug("[MPS][Serial]get select attr val has error:"+e.getMessage());
                return null;
            }
        };
        Map<String, Object> attrValMap = selectExprStream.collect(Collectors.toMap(keyFun, valFun));
        try {
            BeanHelper.setMultiAttrVal(targetObj, attrValMap);
        }catch (Exception e){
            String bb = "[MPS][Serial]batch set attrVal fail,error:"+e.getMessage();
            logger.debug(bb);
        }
    }
}
